Add C++ full-body tracking examples#807
Conversation
|
📝 Docs preview is not auto-deployed for fork PRs. A maintainer with write access to |
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds a C++ full-body pose printer and a C++ MCAP recorder. The examples create Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant FullBodyTrackerPico
participant OpenXRSession
participant DeviceIOSession
participant MCAPWriter
participant replay_full_body.py
FullBodyTrackerPico->>OpenXRSession: provide required extensions
OpenXRSession->>DeviceIOSession: start session with full_body recording config
DeviceIOSession->>MCAPWriter: write full_body topics
DeviceIOSession->>DeviceIOSession: update until duration elapses
MCAPWriter-->>replay_full_body.py: provide recorded full_body topics
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@examples/schemaio/full_body_printer.cpp`:
- Around line 91-105: Bound the sampling loop in the full-body printer so it
cannot run indefinitely when tracked.data remains null. Add a wall-clock
deadline or maximum update count around the while loop, exit when the bound is
reached, and report that no body-tracking samples arrived while preserving the
existing sample-count termination and printing behavior.
- Around line 50-57: Update the sample output around the pelvis and head pose
retrieval to check each joint’s own is_valid() status before printing
coordinates. Print an unavailable marker for an invalid pelvis or head, while
preserving coordinate output independently for each valid joint; do not rely on
the aggregate valid_count or skeleton-level tracking flag.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 95415ff7-5082-44cc-b921-bd680e6ab51d
📒 Files selected for processing (8)
docs/source/device/body_tracking.rstdocs/source/device/trackers.rstdocs/source/references/mcap_record_replay.rstexamples/mcap_record_replay/CMakeLists.txtexamples/mcap_record_replay/cpp/CMakeLists.txtexamples/mcap_record_replay/cpp/record_full_body.cppexamples/schemaio/CMakeLists.txtexamples/schemaio/full_body_printer.cpp
19ffc03 to
9868fd6
Compare
aristarkhovNV
left a comment
There was a problem hiding this comment.
LGTM, I wonder if we could both print and record in one sample. Recording is like one extra line of setup.
- examples/schemaio/full_body_printer.cpp: minimal C++ reader for FullBodyTrackerPico (XR_BD_body_tracking, 24 joints), following the se3_printer pattern. - examples/mcap_record_replay/cpp/record_full_body.cpp: C++ counterpart of record_full_body.py; records the full_body channel by passing a McapRecordingConfig to DeviceIOSession::run(), producing files that replay unchanged with replay_full_body.py. - Reference both examples from the body-tracking, trackers, and MCAP record/replay docs. Signed-off-by: Jiwen Cai <jiwenc@nvidia.com>
Wire the full-body tracking C++ examples into the rig launcher so one command brings up the whole session instead of a hand-started runtime: - rigs/full_body.yaml: first consumer-only rig — no producer plugin and no collection_id; the printer (validity gate) and the MCAP recorder read XR_BD_body_tracking joints directly from the runtime. No params: the recorder keeps its own defaults, and a fresh timestamped .mcap is written per Enter-rerun. - full_body_printer: print '[body tracking inactive]' once per second while body tracking is unavailable (limp mode), sharing the literal record_full_body already uses, so the rig's validity-gate pane is never silently mute. - rig_tests: load + footgun tests for the shipped rig, mirroring the se3_tracker pair. - docs: rig launch pointers in body_tracking.rst and mcap_record_replay.rst, a limp-mode troubleshooting entry, and rig.rst now documents the consumer-only rig shape (collection_id rendezvous scoped to producer rigs). Build green (full_body_printer, record_full_body), rig tests 30/30, pre-commit and Sphinx docs clean. Signed-off-by: Jiwen Cai <jiwenc@nvidia.com>
Follow-up to the generic FullBodyTracker refactor (NVIDIA#781), which removed deviceio_trackers/full_body_tracker_pico.hpp and renamed the Pico types: FullBodyTrackerPico -> FullBodyTracker, FullBodyPosePicoT -> FullBodyPoseT, BodyJointPico_* -> BodyJoint_*. full_body_printer and record_full_body now use the new header and names; no behavior change (the session still selects the default vendor). Both targets build, rig tests 30/30, clang-format-14 and pre-commit clean. Signed-off-by: Jiwen Cai <jiwenc@nvidia.com>
9868fd6 to
654cf7d
Compare
- full_body_printer: gate the pelvis/head printout on each joint's own is_valid flag ([not tracked] marker instead of unspecified coordinates), and bound the read loop (2x the sample budget) so limp mode cannot spin forever — a zero-sample run now exits with a clear message. - Keep the C++ examples self-contained: drop all references to the Python examples from sources, comments, and the recorder's stdout (the rig file pointer stays; the two-ways-to-read-full-body story lives in the docs). - Drop CMAKE_DL_LIBS from both example targets: dl is propagated transitively by the OpenXR loader; verified by linking without it. Signed-off-by: Jiwen Cai <jiwenc@nvidia.com>
Running the full_body rig dropped full_body_<timestamp>.mcap into the repo root (the pane cwd), showing up as untracked noise in git status. - record_full_body: the output argument may now be a directory (existing or with a trailing slash) — it is created if needed and each run writes a fresh timestamped file inside it, so reruns still never clobber. - rigs/full_body.yaml: point the recorder at examples/mcap_record_replay/recordings/ — already gitignored and the default search location of the replay workflow, so a bare replay invocation picks up rig takes automatically. - body_tracking.rst: document where takes land. Verified all three output modes (dir arg creates the directory and timestamps inside; explicit .mcap path unchanged; bare default unchanged); rig tests 30/30; clang-format-14 and pre-commit clean. Signed-off-by: Jiwen Cai <jiwenc@nvidia.com>
aristarkhovNV
left a comment
There was a problem hiding this comment.
update the description to refer to generic full body tracker, pico naming is now deprecated
Summary
Full-body tracking (
FullBodyTrackerPico,XR_BD_body_tracking) was fully supported in the C++ DeviceIO API but only demonstrated from Python. This adds the missing C++ examples and wires them into the docs.examples/schemaio/full_body_printer.cpp— minimal C++ reader for the 24-joint body skeleton, following these3_printerpattern (DeviceIOSession+ tracker, ~30 Hz print loop with per-jointis_validgating).examples/mcap_record_replay/cpp/record_full_body.cpp— C++ counterpart ofrecord_full_body.py: records thefull_bodychannel by passing acore::McapRecordingConfigtoDeviceIOSession::run(). It uses the same channel base name asFullBodySource, so recordings replay unchanged withreplay_full_body.py(record in C++, replay/visualize in Python).device/body_tracking.rst,device/trackers.rst, andreferences/mcap_record_replay.rstnow reference the C++ examples, including a note on C++-side MCAP recording.Testing
full_body_printer,record_full_body).clang-format-14clean;SKIP=check-copyright-year pre-commit run --all-filespasses.NV_CXR_RUNTIME_DIRguidance, matching the sibling examples.<source name>/<sub_channel>).Summary by CodeRabbit